using System;
using System.Collections.Generic;
using LogSystem;
using UnityEditor;
using Cinemachine;
using UnityEditorInternal;
using UnityEngine;
using Yoozoo.Gameplay.City;

namespace Yoozoo.Gameplay.CityEditor
{
    [CustomEditor(typeof(RoomData))]
    public class RoomDataEditor : UnityEditor.Editor
    {
        private const string configPath = "Assets/Arts/Tools/Config/cityFeatureConfig.json";
        private static CityFeatureConfig _featureConfig;
        private RoomData _roomData;

        private SerializedProperty m_idProp;
        private SerializedProperty m_nameProp;
        private SerializedProperty m_arrowProp;
        private SerializedProperty m_scaleProp;
        private SerializedProperty m_jumpPointProp;
        private SerializedProperty m_randomRootProp;
        private SerializedProperty m_outRandomRootProp;
        private SerializedProperty m_boundProp;
        private SerializedProperty m_virtualCamera;
        private SerializedProperty m_portraitVirtualCamera;

        private static GUIContent eventreaderText = EditorGUIUtility.TrTextContent("小人事件点集合", "用于小人生成、目标点以及事件执行");
        private SerializedProperty m_eventListProp;
        private ReorderableList m_eventPointRenderList;

        private static GUIContent collidereaderText = EditorGUIUtility.TrTextContent("点击碰撞体集合", "用于检测房间被点击、被拖动等行为");
        private SerializedProperty m_colliderListProp;
        private ReorderableList m_colliderRenderList;
        
        private static GUIContent hudPointHeaderText = EditorGUIUtility.TrTextContent("建筑的HUD挂点集合", "用于Hud显示的挂点");
        private SerializedProperty m_hudPointListProp;
        private ReorderableList m_hudPointRenderList;
        
        
        
        private void OnEnable()
        {
            UpdateCityConfig();
            _roomData = target as RoomData;

            m_idProp = serializedObject.FindProperty("rID");
            m_nameProp = serializedObject.FindProperty("roomName");
            m_arrowProp = serializedObject.FindProperty("arrow");
            m_scaleProp = serializedObject.FindProperty("editorScale");
            m_jumpPointProp = serializedObject.FindProperty("jumpPoint");
            m_boundProp = serializedObject.FindProperty("bound");
            m_virtualCamera = serializedObject.FindProperty("currentVirtualCamera");
            m_portraitVirtualCamera = serializedObject.FindProperty("portraitVirtualCamera");
            m_randomRootProp = serializedObject.FindProperty("randomPointsRoot");
            m_outRandomRootProp = serializedObject.FindProperty("outRandomPointsRoot");
            
            // m_eventListProp = serializedObject.FindProperty("npcPoints");
            // m_eventPointRenderList = new ReorderableList(serializedObject, m_eventListProp, true, true, true, true);
            // DrawEventListLayout(m_eventPointRenderList, m_eventListProp);

            m_colliderListProp = serializedObject.FindProperty("colliders");
            m_colliderRenderList = new ReorderableList(serializedObject, m_colliderListProp, true, true,true, true);
            DrawColliderListLayout(m_colliderRenderList, m_colliderListProp);
            
            m_hudPointListProp = serializedObject.FindProperty("hudPoints");
            m_hudPointRenderList = new ReorderableList(serializedObject, m_hudPointListProp, true, true,true, true);
            DrawHudPointListLayout(m_hudPointRenderList, m_hudPointListProp);
        }

        public static void UpdateCityConfig()
        {
            var jsonText = AssetDatabase.LoadAssetAtPath<TextAsset>(configPath);
            _featureConfig = JsonUtility.FromJson<CityFeatureConfig>(jsonText.text);
        }
      
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            m_idProp.intValue = EditorGUILayout.IntField("房间ID", m_idProp.intValue);
            m_nameProp.stringValue = EditorGUILayout.TextField("房间名字", m_nameProp.stringValue);
            m_arrowProp.objectReferenceValue = EditorGUILayout.ObjectField("方向指示", m_arrowProp.objectReferenceValue, typeof(Mesh), true) as Mesh;
            m_jumpPointProp.objectReferenceValue = EditorGUILayout.ObjectField("跳转点", m_jumpPointProp.objectReferenceValue, typeof(Transform), true) as Transform;
            m_boundProp.objectReferenceValue = EditorGUILayout.ObjectField("边界框", m_boundProp.objectReferenceValue, typeof(SpriteRenderer), true) as SpriteRenderer;
            m_virtualCamera.objectReferenceValue = EditorGUILayout.ObjectField("虚拟相机(横版)", m_virtualCamera.objectReferenceValue, typeof(CinemachineVirtualCamera), true) as CinemachineVirtualCamera;
            m_portraitVirtualCamera.objectReferenceValue = EditorGUILayout.ObjectField("虚拟相机(竖版)", m_portraitVirtualCamera.objectReferenceValue, typeof(CinemachineVirtualCamera), true) as CinemachineVirtualCamera;
            //m_randomRootProp.objectReferenceValue = EditorGUILayout.ObjectField("随机路点父节点", m_randomRootProp.objectReferenceValue, typeof(Transform), true) as Transform;
            //m_outRandomRootProp.objectReferenceValue = EditorGUILayout.ObjectField("外围随机路点父节点", m_outRandomRootProp.objectReferenceValue, typeof(Transform), true) as Transform;
            
            
            EditorGUILayout.Space(10);
            m_colliderRenderList.DoLayoutList();
            EditorGUILayout.Space(10);



            m_scaleProp.vector3Value = EditorGUILayout.Vector3Field("Hud缩放", m_scaleProp.vector3Value);
            if (GUILayout.Button("设置房间所有Hud缩放",GUILayout.Height(30)))
            {
                if (_roomData && _roomData.hudPoints!=null)
                {
                    foreach (var hudPoint in _roomData.hudPoints)
                    {
                        hudPoint.hPos.transform.localScale = m_scaleProp.vector3Value;
                    }
                }   
            }
            
            if (GUILayout.Button("更新房间所有Hud缩放z为0的节点 (模拟器会显示方块)",GUILayout.Height(30)))
            {
                if (_roomData && _roomData.hudPoints!=null)
                {
                    foreach (var hudPoint in _roomData.hudPoints)
                    {
                        if (hudPoint.hPos.transform.localScale.z <= 0)
                        {
                            hudPoint.hPos.transform.localScale = new Vector3(hudPoint.hPos.transform.localScale.x, hudPoint.hPos.transform.localScale.y, hudPoint.hPos.transform.localScale.x);
                            UnityEngine.Debug.Log($"发现z轴缩放为0的节点{hudPoint.hPos.transform.name}，已经修复");
                        }
                    }
                }   
            }
            
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("打开全部Hud预览",GUILayout.Height(35)))
            {
                if (_roomData && _roomData.hudPoints!=null)
                {
                    foreach (var hudPoint in _roomData.hudPoints)
                    {
                        _roomData.PreviewHud(hudPoint);
                    }
                }   
            }
            if (GUILayout.Button("取消全部Hud预览",GUILayout.Height(35)))
            {
                if (_roomData && _roomData.hudPoints!=null)
                {
                    foreach (var hudPoint in _roomData.hudPoints)
                    {
                        _roomData.UnPreviewHud(hudPoint);
                    }
                }   
            }
            EditorGUILayout.EndHorizontal();

            
            EditorGUILayout.Space(10);
            m_hudPointRenderList.DoLayoutList();

            
            serializedObject.ApplyModifiedProperties();

        }

        private void DrawEventListLayout(ReorderableList list, SerializedProperty prop)
        {
            //EditorGUIUtility.labelWidth = 100;
            list.elementHeight = EditorGUIUtility.singleLineHeight * 1.25f * 4 + 10;
            list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                var element = prop.GetArrayElementAtIndex(index);

                SerializedProperty posProperty = element.FindPropertyRelative("eventPoint");
                Rect posRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                EditorGUI.ObjectField(posRect, posProperty, new GUIContent("挂点"));

                rect.y += posRect.height + 5;

                SerializedProperty nameProperty = element.FindPropertyRelative("eventName");
                Rect nameRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                nameProperty.stringValue = EditorGUI.TextField(nameRect, "事件名称", nameProperty.stringValue);

                rect.y += nameRect.height + 5;

                SerializedProperty timeProperty = element.FindPropertyRelative("needTime");
                Rect timeRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                timeProperty.intValue = EditorGUI.IntField(timeRect, "事件花费时间/毫秒", timeProperty.intValue);

                rect.y += timeRect.height + 5;

                SerializedProperty rotateProperty = element.FindPropertyRelative("rotate");
                Rect rotateRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                rotateProperty.floatValue = EditorGUI.FloatField(rotateRect, "y轴旋转角度", rotateProperty.floatValue);
                //SerializedProperty timeProperty = element.FindPropertyRelative("needTime");
                //Rect timeRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                //EditorGUI.IntField(timeRect, timeProperty.intValue, new GUIStyle("事件执行的时间"));

                //rect.y += timeRect.height + 10;
            };

            



            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, eventreaderText);
            };

            list.onCanRemoveCallback = li => { return li.count > 0; };

        }
        
        private void DrawColliderListLayout(ReorderableList list, SerializedProperty prop)
        {
            EditorGUIUtility.labelWidth = 100;
            list.elementHeight = EditorGUIUtility.singleLineHeight * 1.25f;
            list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                var element = prop.GetArrayElementAtIndex(index);
                EditorGUI.ObjectField(rect, element,new GUIContent(index.ToString()));
            };
            
            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, collidereaderText);
            };
            
            list.onCanRemoveCallback = li => { return li.count > 0; };
            
        }


        private Dictionary<string, GameObject> hudPrefabCache = new Dictionary<string, GameObject>();

        private void DrawHudPointListLayout(ReorderableList list, SerializedProperty prop)
        {
            list.elementHeight = EditorGUIUtility.singleLineHeight * 1.25f * 6 + 10;
            
            list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
            {
                EditorGUIUtility.labelWidth = 100;

                var element = prop.GetArrayElementAtIndex(index);
                rect.y += 2;
                rect.x += 10;
                
                SerializedProperty idProperty = element.FindPropertyRelative("hID");
                Rect idRect = new Rect(rect.x, rect.y, 360, EditorGUIUtility.singleLineHeight);
                idProperty.intValue = (int)(CityHudEnum)EditorGUI.EnumPopup(idRect, "", (CityHudEnum)idProperty.intValue);
                //idProperty.intValue = EditorGUI.IntField(idRect, "Hud类型ID", idProperty.intValue);
                
                rect.y += idRect.height + 5;
                SerializedProperty posProperty = element.FindPropertyRelative("hPos");
                Rect posRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                EditorGUI.ObjectField(posRect,posProperty,new GUIContent("挂点"));
                
               
                if (_featureConfig != null)
                {
                    HudFeature hudFeature = _featureConfig.GetHudFeature(idProperty.intValue);
                    if (hudFeature != null)
                    {
                        GUI.enabled = false;
                        rect.y += idRect.height + 5;
                        Rect pathRect = new Rect(rect.x, rect.y, 480, EditorGUIUtility.singleLineHeight);
                        EditorGUI.TextField(pathRect, "预设体路径",hudFeature.HudPrefabPath);

                        rect.y += idRect.height + 5;
                        Rect prefabRect = new Rect(rect.x, rect.y, 280, EditorGUIUtility.singleLineHeight);
                        if (!hudPrefabCache.ContainsKey(hudFeature.HudPrefabPath))
                        {
                            hudPrefabCache[hudFeature.HudPrefabPath] =
                                AssetDatabase.LoadAssetAtPath<GameObject>(hudFeature.HudPrefabPath);
                        }
                        EditorGUI.ObjectField(prefabRect, "预设体",hudPrefabCache[hudFeature.HudPrefabPath], typeof(GameObject));
                        GUI.enabled = true;
                    }
                }

                rect.y += idRect.height + 10;
                
                Rect previewRect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight * 2);
                if (GUI.Button(previewRect, "预览"))
                {
                    _roomData.PreviewHud(_roomData.hudPoints[index]);
                    //Debug.LogError(LogModule.CityRoom,"预览");
                }

                Rect unPreviewRect = new Rect(rect.x + previewRect.width + 20, rect.y , 120, EditorGUIUtility.singleLineHeight * 2);
                if (_roomData.hudPoints[index].hPos && _roomData.hudPoints[index].hPos.childCount > 0)
                {
                    if (GUI.Button(unPreviewRect, "取消预览"))
                    {
                        _roomData.UnPreviewHud(_roomData.hudPoints[index]);
                        //Debug.LogError(LogModule.CityRoom,"取消预览");
                    }
                }

            };
            
            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, hudPointHeaderText);
            };
            
            list.onCanRemoveCallback = li => { return li.count > 0; };   
        }
    }
}